﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Diagnostics;
using System.IO;
using System.Collections;
using System.Data.SqlClient;
using System.Data;
using SpeechLib;
using System.Web.UI.WebControls;

//namespace ExtensionMethodDump
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var song = new { Artist = "Jussi Bjorling", Song = "Aida" };
//            song.Dump();
//            Console.ReadLine();
//        }
//    }

//    public static class Dumper
//    {
//        public static void Dump(this object o)
//        {
//            PropertyInfo[] properties = o.GetType().GetProperties();
//            foreach (var p in properties)
//            {
//                try
//                {
//                    Debug.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, p.GetValue(o, null)));
//                }
//                catch (Exception)
//                {
//                    Debug.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, "unk."));
//                }
//            }
//        }
//    }
//}

//namespace ExtensionWithReturn
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var songs = new { Artist = "Green Day", Song = "Wake Me Up When September Ends" };
//            Console.WriteLine(songs.Dump());
//            Console.ReadLine();
//        }
//    }

//    public static class Dumper
//    {
//        public static string Dump(this object o)
//        {
//            PropertyInfo[] properties = o.GetType().GetProperties();
//            StringBuilder builder = new StringBuilder();
//            foreach (PropertyInfo p in properties)
//            {
//                try
//                {
//                    builder.AppendFormat(string.Format("Name: {0}, Value: {1}", p.Name, p.GetValue(o, null)));
//                }
//                catch (Exception)
//                {
//                    builder.AppendFormat(string.Format("Name: {0}, Value: {1}", p.Name, "unk."));
//                }
//                builder.AppendLine();
//            }

//            return builder.ToString();
//        }
//    }
//}

//namespace ExtensionMethodWithAdditionalParameters
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var song = new { Artist = "Avril Lavigne", Song = "My Happy Ending" };

//            song.Dump(Console.Out);
//            Console.ReadLine();
//        }
//    }

//    public static class Dumper
//    {
//        public static void Dump(this object o, TextWriter writer)
//        {
//            PropertyInfo[] properties = o.GetType().GetProperties();
//            foreach (PropertyInfo p in properties)
//            {
//                try
//                {
//                    writer.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, p.GetValue(o, null)));
//                }
//                catch (Exception)
//                {
//                    writer.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, "unk."));
//                }
//            }
//        }
//    }
//}

//namespace OverloadedExtensionDump
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var songs = new[] {
//                new { Artist = "Jussi Bjorling", Song = "Aida" },
//                new { Artist = "Sheryl Crow", Song = "Steve McQueen" }
//            };

//            songs.Dump();
//            Console.ReadLine();
//        }
//    }

//    public static class Dumper
//    {
//        public static void Dump(this object o)
//        {
//            PropertyInfo[] properties = o.GetType().GetProperties();
//            foreach (PropertyInfo p in properties)
//            {
//                try
//                {
//                    Debug.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, p.GetValue(o, null)));
//                }
//                catch (Exception)
//                {
//                    Debug.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, "unk."));
//                }
//            }
//        }

//        public static void Dump(this IList list)
//        {
//            foreach (object o in list)
//            {
//                o.Dump();
//            }
//        }
//    }
//}

//namespace GenericExtensionMethod
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            string connectionString = "Data Source=ZYAN9\\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True";
//            // create the list of orders
//            List<Order> orders = new List<Order>();
//            // open and protect the connection
//            using (SqlConnection connection = new SqlConnection(connectionString))
//            {
//                // prepare to select all orders
//                SqlCommand command = new SqlCommand("SELECT * FROM ORDERS", connection);
//                command.CommandType = System.Data.CommandType.Text;
//                connection.Open();
//                SqlDataReader reader = command.ExecuteReader(); ;

//                while (reader.Read())
//                {
//                    Order order = new Order();
//                    // the extension method does the legwork but it looks like order
//                    // is self-initializing
//                    order.Read(reader);
//                    orders.Add(order);
//                }
//            }

//            // use the dumper to send everything to the console
//            orders.Dump(Console.Out);
//            Console.ReadLine();
//        }
//    }

//    public static class ReaderHelper
//    {
//        public static void Read(this Order order, IDataReader reader)
//        {
//            order.OrderID = order.SafeRead(reader, "OrderID", -1);
//            order.CustomerID = order.SafeRead(reader, "CustomerID", "");
//        }

//        public static T SafeRead<T>(this EntityClass order, IDataReader reader, string fieldName, T defaultValue)
//        {
//            try
//            {
//                object o = reader[fieldName];
//                if (o == null || o == DBNull.Value)
//                    return defaultValue;

//                return (T)Convert.ChangeType(o, defaultValue.GetType());
//            }
//            catch (Exception)
//            {
//                return defaultValue;
//            }
//        }
//    }

//    public static class Dumper
//    {
//        public static void Dump(this object o, TextWriter writer)
//        {
//            PropertyInfo[] properties = o.GetType().GetProperties();
//            foreach (PropertyInfo p in properties)
//            {
//                try
//                {
//                    writer.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, p.GetValue(o, null)));
//                }
//                catch (Exception)
//                {
//                    writer.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, "unk."));
//                }
//            }
//        }

//        public static void Dump<T>(this IList<T> list, TextWriter writer)
//        {
//            foreach (object o in list)
//                o.Dump(writer);
//        }
//    }

//    public class EntityClass { }
//    public class Order : EntityClass
//    {
//        /// <summary>
//        /// Initializes a new instance of the Order class.
//        /// </summary>
//        public Order()
//        {
//        }

//        private int orderID;
//        public int OrderID
//        {
//            get { return orderID; }
//            set { orderID = value; }
//        }

//        private string customerID;
//        public string CustomerID
//        {
//            get { return customerID; }
//            set { customerID = value; }
//        }
//    }
//}

//namespace QueryWithWhere
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var numbers = new int[] { 1966, 1967, 1968, 1969, 1970 };
//            var evens = from num in numbers where num % 2 == 0 select num;

//            foreach (var result in evens)
//                Console.WriteLine(result);

//            Console.ReadLine();
//        }
//    }
//}

//namespace QueryWithWhereLongForm
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            var numbers = new int[] { 1966, 1967, 1968, 1969, 1970 };
//            Func<int, bool> getEvents = delegate(int num)
//            {
//                return num % 2 == 0;
//            };

//            var evens = numbers.Where<int>(getEvents);
//            IEnumerator enumerator = evens.GetEnumerator();

//            while (enumerator.MoveNext())
//                Console.WriteLine(enumerator.Current);
            
//            Console.ReadLine();
//        }
//    }
//}

//namespace TalkingStringClass
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            "Microsoft Surface is Cool!".Say();
//            "Press Enter to Quit".Say();
//            Console.ReadLine();
//        }
//    }

//    public static class MakeItTalk
//    {
//        public static void Say(this string s)
//        {
//            //SpVoice voice = new SpVoiceClass();
//            SpVoice voice = new SpVoice();
//            // requiredattributes - no attributes are required
//            // optionalattributes - nonrequired
//            ISpeechObjectTokens tokens = voice.GetVoices("", "");
//            voice.Rate = 2;
//            voice.Volume = 100;
//            voice.Voice = tokens.Item(0);
//            voice.Speak(s, SpeechVoiceSpeakFlags.SVSFDefault);
//        }
//    }
//}

namespace PartialMethodDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            CustomerList customers = new CustomerList
            {
                new Customer { CustomerID = 1, Name = "Levi, Ray and Shoup" },
                new Customer { CustomerID = 2, Name = "General Dynamics Land Systems" },
                new Customer { CustomerID = 3, Name = "Microsoft" }
            };

            customers.Dump();
            Console.ReadLine();
        }
    }

    public partial class CustomerList
    {
        private string propertyName;
        private SortDirection direction;

        partial void SpecialSort(string propertyName, SortDirection direction)
        {
            this.propertyName = propertyName;
            this.direction = direction;
            Sort(MyComparer);
        }

        /// <summary>
        /// Using an integer to change the direction of the sort was a suggestion made by
        /// Chris Chartran, my good friend from Canada
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        private int MyComparer(Customer x, Customer y)
        {
            PropertyInfo lhs = x.GetType().GetProperty(propertyName);
            PropertyInfo rhs = y.GetType().GetProperty(propertyName);
            int directionChanger = direction == SortDirection.Ascending ? 1 : -1;

            object o1 = lhs.GetValue(x, null);
            object o2 = rhs.GetValue(y, null);

            if (o1 is IComparable && o2 is IComparable)
                return ((IComparable)o1).CompareTo(o2) * directionChanger;

            // no sort
            return 0;
        }
    }

    public partial class CustomerList : List<Customer>
    {
        partial void SpecialSort(string propertyName, SortDirection direction);

        public void Dump()
        {
            SpecialSort("CustomerID", SortDirection.Descending);

            foreach (var customer in this)
                Console.WriteLine(customer.ToString());
        }
    }

    public class Customer
    {
        private int customerID;
        public int CustomerID
        {
            get { return customerID; }
            set { customerID = value; }
        }

        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public override string ToString()
        {
            return string.Format("CustomerID={0}, Name={1}", customerID, name);
        }
    }
}
